package com.dondedesigns.eh.persistence;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.dondedesigns.eh.util.MessageConstants;
import com.opensymphony.xwork2.validator.annotations.EmailValidator;
import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;

@Entity
@Table (name="USERS")
public class User {
	@Id @GeneratedValue
	@Column (name="ID_USERS")
	private Long id;
	
	@Column (name="USERNAME", unique=true, nullable=false)
	private String username;
	
	@Column (name="NAME", nullable=false)
	private String name;
	
	@Column (name="PASSWORD", nullable=false)
	private String password;
	
	@Transient
	private String confirmPassword;
	
	@Column (name="EMAIL", unique=true, nullable=false)
	private String email;
	
	@Column(name="APPROVED", nullable=false)
	private ApprovedStatus approvedStatus;
	
	@ManyToOne (cascade=CascadeType.ALL)
	@JoinColumn (name="ROLE")
	private Role role; 
	
	
	@OneToMany (cascade=CascadeType.ALL, mappedBy="user", fetch=FetchType.LAZY)
	private Set<BlUser> blUsers;
	
	public User() {
		blUsers = new HashSet<BlUser>();
		approvedStatus = ApprovedStatus.PENDENT;
	}

	public Long getId() {
		return id;
	}

	@SuppressWarnings("unused")
	private void setId(Long id) {
		this.id = id;
	}

	@RequiredFieldValidator (type = ValidatorType.FIELD, fieldName="username", message=MessageConstants.USERNAME_REQUIRED)
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	
	public void setApprovedStatus(ApprovedStatus approvedStatus) {
		this.approvedStatus = approvedStatus;
	}

	public ApprovedStatus getApprovedStatus() {
		return approvedStatus;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public Set<BlUser> getBlUsers() {
		return blUsers;
	}

	public void setBlUsers(Set<BlUser> blUsers) {
		this.blUsers = blUsers;
	}
	
	public void addBlUser (BlUser blUser) {
		this.getBlUsers().add(blUser);
		blUser.setUser(this);
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("ID: "+id+"\nUsername: "+username+"\nPassword: "+password+"\nEmail: "+email);
		builder.append("\n\nBLUSERS");
		for (BlUser blUser : this.getBlUsers()) {
			builder.append("\nBlUser: "+blUser.getUsername());
			builder.append("\n\nBULLETS");
			for(Bullet bullet : blUser.getBullets()) {
				builder.append("\nBullets: "+bullet.getAmount()+"\t"+bullet.getGun()+"\t"+bullet.getUpdateDate());
			}
			builder.append("\n\nTAXES");
			for(Taxes taxes : blUser.getTaxes()) {
				builder.append("\nTaxes: "+taxes.getAmount()+"\t"+taxes.getPaymentDate());
			}
		}
		return builder.toString();
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof User) {
			User user = (User) obj;
			if (user.username.equals(this.username)) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return this.username.hashCode();
	}

}
